<script lang="ts" setup>
const oldPaddingTop = ref("");
const oldPaddingBottom = ref("");
const oldOverflow = ref("");

const collapseBeforeEnter = (el) => {
  oldPaddingTop.value = el.style.paddingTop;
  oldPaddingBottom.value = el.style.paddingBottom;
  el.style.paddingTop = "0";
  el.style.paddingBottom = "0";
  el.style.maxHeight = "0";
};

const collapseEnter = (el, done) => {
  oldOverflow.value = el.style.overflow;
  let elHeight = el.scrollHeight;
  if (elHeight > 0) {
    el.style.maxHeight = elHeight + "px";
  } else {
    el.style.maxHeight = "0";
  }
  el.style.paddingTop = oldPaddingTop.value;
  el.style.paddingBottom = oldPaddingBottom.value;

  el.style.overflow = "hidden";
  let onTransitionDone = function () {
    done();
    el.removeEventListener("transitionend", onTransitionDone, false);
    el.removeEventListener("transitioncancel", onTransitionDone, false);
  };
  // 绑定元素的transition完成事件，在transition完成后立即完成vue的过度动效
  el.addEventListener("transitionend", onTransitionDone, false);
  el.addEventListener("transitioncancel", onTransitionDone, false);
};

const collapseAfterEnter = (el) => {
  el.style.maxHeight = "";
  el.style.overflow = oldOverflow.value;
};

const collapseBeforeLeave = (el) => {
  oldPaddingBottom.value = el.style.paddingBottom;
  oldPaddingTop.value = el.style.paddingTop;
  oldOverflow.value = el.style.overflow;

  el.style.maxHeight = el.scrollHeight + "px";
  el.style.overflow = "hidden";
};

const collapseLeave = (el, done) => {
  if (el.scrollHeight !== 0) {
    el.style.maxHeight = "0";
    el.style.paddingBottom = "0";
    el.style.paddingTop = "0";
  }
  let onTransitionDone = function () {
    done();
    el.removeEventListener("transitionend", onTransitionDone, false);
    el.removeEventListener("transitioncancel", onTransitionDone, false);
  };
  // 绑定元素的transition完成事件，在transition完成后立即完成vue的过度动效
  el.addEventListener("transitionend", onTransitionDone, false);
  el.addEventListener("transitioncancel", onTransitionDone, false);
};

const collapseAfterLeave = (el) => {
  el.style.maxHeight = "";
  el.style.overflow = oldOverflow.value;
  el.style.paddingBottom = oldPaddingBottom.value;
  el.style.paddingTop = oldPaddingTop.value;

  oldOverflow.value = oldPaddingBottom.value = oldPaddingTop.value = "";
};
</script>
<template>
  <transition
    name="collapse-transition"
    @enter="collapseEnter"
    @leave="collapseLeave"
    @before-enter="collapseBeforeEnter"
    @after-enter="collapseAfterEnter"
    @before-leave="collapseBeforeLeave"
    @after-leave="collapseAfterLeave"
  >
    <slot></slot>
  </transition>
</template>

<style lang="scss" scoped>
.collapse-transition-enter-active,
.collapse-transition-leave-active {
  transition: height 0.3s ease-in-out, padding 0.3s ease-in-out,
    max-height 0.3s ease-in-out;
}
</style>
